#include "StdAfx.h"
#include "send_buf.h"

namespace fly {

	namespace jld{

		namespace buffer {	

			send_buf::send_buf()
				:base_buf()
				,min_send_size_(header_size_ + min_buf_size_)
				,is_send_(false)
				,const_buf_()
			{
			}


			send_buf::~send_buf()
			{
			}

			bool send_buf::is_send()
			{
				if (is_send_)
				{
					is_send_ = false;
					return true;
				}
				return false;
			}
			void send_buf::set_const_buf()
			{
				//true:reuse the const buf when last const buf has been sent by all the connections
				//false: (use_count ==0) || (use_count >1)
				//0: first time to send the const buf
				//>1: at least 1 connection has not finished sending
				if (const_buf_.unique())
				{
					*const_buf_ = buf_.data();
				} else
				{
					const_buf_.reset(new asio::streambuf::const_buffers_type(buf_.data()));
				}
			}
			bool send_buf::serialize_to_send(const PID& pid, const TARGET& target, google::protobuf::Message& message)
			{
				if (message.ByteSize() < min_buf_size_)
				{
					LOG_ERR("Message size must be greater than or equals to ", integer(min_buf_size_));
					return false;
				}
				if (!message.IsInitialized())
				{
					LOG_ERR("Message Uninitialized");
					return false;
				}
				ostream ostr(&buf_);
				Header header;
				header.set_size(message.ByteSize());
				header.set_pid(pid);
				header.SerializeToOstream(&ostr);

				if (is_send_ = message.SerializeToOstream(&ostr))
				{
					set_const_buf();
				}
				consume();
				ostr.clear();

				send_packet packet;
				packet.buf = const_buf_;
				packet.target = target;
				packets_.push(packet);
				return is_send_;
			}

			queue<send_packet>& send_buf::packets()
			{
				return packets_;
			}
		}
	}
}